#ifndef __DOCUMENTS_CONTAINER_H__
#define __DOCUMENTS_CONTAINER_H__

#include <string>
#include <vector>
#include "document.h"

namespace invertedindex{

class DocumentsContainer{
	private:
		/*set containing documents*/
		typedef std::vector<Document*> Documents;
		Documents docs;
 
	public:
		DocumentsContainer(){
		}
		
		DocumentsContainer(const DocumentsContainer& dc){
			unsigned int i=0;
			while(i<dc.getDocumentCount()){
				docs.insert(docs.end(),dc.getDocument(i).second);
				i++;
			}
		}


		~DocumentsContainer(){
			for(Documents::iterator it=docs.begin();it!=docs.end();++it){
				delete(*it);
			}
			docs.clear();
		}

		void setFields(const DocumentsContainer& dc){
			unsigned int i=0;
			while(i<dc.getDocumentCount()){
				docs.insert(docs.end(),dc.getDocument(i).second);
				i++;
			}
		}


				
		bool insertDocument(const Document& document){
			bool encontro = false;
			Documents::iterator it = docs.begin();
			unsigned int i=0;
			while((i<docs.size())&&(!encontro)){
				if(((*it)->getId())>=document.getId())
					encontro=true;
				else{
					it++;
					i++;
				}
			}

			if(!((encontro)&&(((*it)->getId())==document.getId()))){
				if(encontro==false)
					it=docs.end();
				Documents::iterator p=docs.insert(it,document.duplicate());
				return true;

			}
			return false;
		}
		
		bool removeDocument(const Document& document){
			bool encontro = false;
			Documents::iterator it = docs.begin();
			unsigned int i=0;
			while((i<docs.size())&&(!encontro)){
				if((*it)->getId()>=document.getId())
					encontro=true;
				else{
					it++;
					i++;
				}
			}

		
			if((it!=docs.end())&&((*it)->getId()==document.getId())){
				delete (*it);
				docs.erase(it);
				return true;
			}

			return false;
		}

		
		unsigned int getDocumentCount()const{
			return docs.size(); 
		}
				
		std::pair<bool, Document*> getDocument(unsigned int index) const{
			std::pair<bool, Document*> ret(false,NULL);
			if(index<docs.size()){
				ret.second=(docs.at(index))->duplicate();
				ret.first=true;
			}
			return ret; 
		}
		
		
		std::pair<bool, unsigned int> getIdOfDocument(unsigned int documentIndex) const{
			std::pair<bool, unsigned int> ret(false,NULL);
			if(documentIndex<docs.size()){
				ret.second=(docs.at(documentIndex))->getId();
				ret.first=true;
			}
			return ret; 
		}
		
		std::pair<bool, unsigned int> getNumberOfOccurrencesInDocument(unsigned int documentIndex) const{
			std::pair<bool, unsigned> ret(false,NULL);
			if(documentIndex<docs.size()){
				ret.second=(docs.at(documentIndex))->getNumberOfOccurrences();
				ret.first=true;
			}
			return ret; 
		}
		
		std::pair<bool, unsigned int> getOccurrenceInDocument(unsigned int documentIndex, unsigned int occurranceIndex) const{
			std::pair<bool, unsigned int> ret(false,NULL);
			if(documentIndex<docs.size()){
				std::pair<bool, unsigned> p = (docs.at(documentIndex))->getPosition(occurranceIndex);
				ret.second=p.second;
				ret.first=p.first;
			}
			return ret; 
		
		}

		
		std::ostream& toOstream(std::ostream& out)const{
			out<<"\tDocument Container Content:"<<std::endl;
			unsigned int i=0;
			while(i<docs.size()){
				out<<"\tdoc["<<i<<"]:"<<std::endl;
				docs[i]->toOstream(out);
				i++;
			}
			return out;
		}

		bool operator ==(const DocumentsContainer& docC)const{
			bool ret=true;
			unsigned int i=0;
			while((i<(this->docs).size())&&(i<docC.docs.size())&&ret){
				if(!(*docs[i]==*docC.docs[i]))
					ret=false;
				i++;
			}
			if((i<docs.size())||(i<docC.docs.size()))
				ret=false;
			return ret;
		}

};


}

#endif

